home *** CD-ROM | disk | FTP | other *** search
- ; AMSAT/TAPR DSP BPSK demod for PIII satellites
- ; Sample rate should be set to 8000 samples/sec.
- ; code by Bob McGwier N4HY
- ;
- org 0
- b go
- ;
- ; Okay Jose' set up equates for data memory etc.
- ;
- org 10H ; code should begin at memory address 16 cause David
- ; does something strange with locations 0-15. Does
- ; he in fact document this?
-
- sine: equ 0 ; will store sine values from tone
- one: equ 1 ; guess what goes here duhhhhh!
- freq: equ 2 ; PLL frequency stored here
- phase: equ 3 ; PLL phase stored here
- maskl: equ 4 ; mask for fine or low order bits of phase
- mask: equ 5 ; mask for doing modulo 16384 arithmetic with phase
- sinx: equ 6 ; used to store coarse sine value (high order bits)
- cosx: equ 7 ; as above for cosine
- mone: equ 8 ; minus one stored here
- wkph: equ 9 ; different phases (PLL, remodulator tone etc) are stored hr
- ; for frequency synthesis
- masko: equ 10 ; mask for converting on board PCM to DAC format
- mps: equ 11 ; multiplier for quadrant determination for sine
- mpc: equ 12 ; multiplier for quadrant determination for cosine
- siny: equ 13 ; fine correction value for use in SIN(X+Y) = sinx*cosy+
- cosy: equ 14 ; cosx*siny
- cosine: equ 15 ; cosine is also needed for Q arm in Costas loop
- coph: equ 16 ; working number holder
- modem: equ 17 ; Used to choose between complex tone for arms and real tone
- ; in the modulator as explained below
- bitpc: equ 20 ; freqo is assigned one of the values above for remod
-
- xn0: equ 21 ; place for storing all the values for the "I" or data arm
- xn1: equ 22
- xn2: equ 23
- xn3: equ 24
- xn4: equ 25
- xn5: equ 26
- xn6: equ 27
- xn7: equ 28
- xn8: equ 29
- xn9: equ 30
- xn10: equ 31
- xn11: equ 32
- xn12: equ 33
- xn13: equ 34
- xn14: equ 35
- xn15: equ 36
- xn16: equ 37
- xn17: equ 38
- xn18: equ 39
- xn19: equ 40
- xn20: equ 41
- xn21: equ 42
- xn22: equ 43
- yn0: equ 44 ; storage for values in "Q" or phase error arm.
- yn1: equ 45
- yn2: equ 46
- yn3: equ 47
- yn4: equ 48
- yn5: equ 49
- yn6: equ 50
- yn7: equ 51
- yn8: equ 52
- yn9: equ 53
- yn10: equ 54
- yn11: equ 55
- yn12: equ 56
- yn13: equ 57
- yn14: equ 58
- yn15: equ 59
- yn16: equ 60
- yn17: equ 61
- yn18: equ 62
- yn19: equ 63
- yn20: equ 64
- yn21: equ 65
- yn22: equ 66
- c0: equ 67 ; Phase error
- maskf: equ 68 ; frequency mask so that frequency doesn't try and leave
- ; proper range
- H9: equ 69
- H10: equ 70 ; arm filter value too large to use mpyk
- H11: equ 71 ; arm filter value too large to use mpyk
- sweep: equ 74 ; contains sweep value +/- one frequency unit per sample
- highfq: equ 75 ; high end of sweep range
- lowfq: equ 76 ; low end of sweep range
- clkfr: equ 78
- clkph: equ 79
- ch4: equ 80
- ch5: equ 81
- ch6: equ 82
- bd0: equ 83
- bd1: equ 84
- bd2: equ 85
- bd3: equ 86
- bd4: equ 87
- bd5: equ 88
- bd6: equ 89
- bd7: equ 90
- bd8: equ 91
- bd9: equ 92
- bd10: equ 93
- bd11: equ 94
- bd12: equ 95
- cd0: equ 96
- cd1: equ 97
- cd2: equ 98
- cd3: equ 99
- cd4: equ 100
- cd5: equ 101
- cd6: equ 102
- cd7: equ 103
- cd8: equ 104
- cd9: equ 105
- cd10: equ 106
- cd11: equ 107
- cd12: equ 108
- clkav: equ 109
- bit: equ 110
- clock: equ 111
- clocke: equ 112
- bito: equ 115
- bit0: equ 18
- bit1: equ 19
- bita0: equ 113
- bita1: equ 114
- clkit: equ 116
- bitm0: equ 117
- bitm1: equ 118
- tbit: equ 119
- tclk: equ 120
- tfrq: equ 121
- tph: equ 122
- tcnt: equ 123
- carof: equ 124
- inty: equ 125
- eom: equ 126
- sintbl: dw 0 ; coarse sine table in steps of PI/64 radians to PI/2
- dw 804
- dw 1607
- dw 2410
- dw 3211
- dw 4011
- dw 4807
- dw 5601
- dw 6392
- dw 7179
- dw 7961
- dw 8739
- dw 9511
- dw 10278
- dw 11038
- dw 11792
- dw 12539
- dw 13278
- dw 14009
- dw 14732
- dw 15446
- dw 16150
- dw 16845
- dw 17530
- dw 18204
- dw 18867
- dw 19519
- dw 20159
- dw 20787
- dw 21402
- dw 22004
- dw 22594
- dw 23169
- dw 23731
- dw 24278
- dw 24811
- dw 25329
- dw 25831
- dw 26318
- dw 26789
- dw 27244
- dw 27683
- dw 28105
- dw 28510
- dw 28897
- dw 29268
- dw 29621
- dw 29955
- dw 30272
- dw 30571
- dw 30851
- dw 31113
- dw 31356
- dw 31580
- dw 31785
- dw 31970
- dw 32137
- dw 32284
- dw 32412
- dw 32520
- dw 32609
- dw 32678
- dw 32727
- dw 32757
- dw 32767 ; PI/2
- fines: dw 0 ; fine sine table in steps of PI/(64*64) radians to PI/64
- dw 12
- dw 25
- dw 37
- dw 50
- dw 62
- dw 75
- dw 87
- dw 100
- dw 113
- dw 125
- dw 138
- dw 150
- dw 163
- dw 175
- dw 188
- dw 201
- dw 213
- dw 226
- dw 238
- dw 251
- dw 263
- dw 276
- dw 289
- dw 301
- dw 314
- dw 326
- dw 339
- dw 351
- dw 364
- dw 376
- dw 389
- dw 402
- dw 414
- dw 427
- dw 439
- dw 452
- dw 464
- dw 477
- dw 490
- dw 502
- dw 515
- dw 527
- dw 540
- dw 552
- dw 565
- dw 578
- dw 590
- dw 603
- dw 615
- dw 628
- dw 640
- dw 653
- dw 665
- dw 678
- dw 691
- dw 703
- dw 716
- dw 728
- dw 741
- dw 753
- dw 766
- dw 779
- dw 791
- finec: dw 32767 ;ditto to above for fine sine
- dw 32766
- dw 32766
- dw 32766
- dw 32766
- dw 32766
- dw 32766
- dw 32766
- dw 32766
- dw 32766
- dw 32766
- dw 32766
- dw 32766
- dw 32766
- dw 32766
- dw 32766
- dw 32766
- dw 32766
- dw 32766
- dw 32766
- dw 32766
- dw 32765
- dw 32765
- dw 32765
- dw 32765
- dw 32765
- dw 32765
- dw 32765
- dw 32765
- dw 32764
- dw 32764
- dw 32764
- dw 32764
- dw 32764
- dw 32764
- dw 32764
- dw 32763
- dw 32763
- dw 32763
- dw 32763
- dw 32763
- dw 32762
- dw 32762
- dw 32762
- dw 32762
- dw 32762
- dw 32761
- dw 32761
- dw 32761
- dw 32761
- dw 32760
- dw 32760
- dw 32760
- dw 32760
- dw 32759
- dw 32759
- dw 32759
- dw 32759
- dw 32758
- dw 32758
- dw 32758
- dw 32758
- dw 32757
- dw 32757
- armfilt: dw 5054 ; H9
- dw 7679 ; H10
- dw 8706 ; H11
- dw 4769 ; CH4
- dw 6557 ; CH5
- dw 7249 ; CH6
- go: ldpk 0 ; make sure that we are pointing to 0 data page
- larp ar0
- lark ar0,1
- lark ar1,19
- lack one ; make and store one
- sacl one
-
- lack armfilt ; store address of the too large coefficients
- tblr H9
- add one
- tblr H10
- add one
- tblr H11
- add one
- tblr CH4
- add one
- tblr ch5
- add one
- tblr ch6
- lac one,11 ; make and store DAC converter mask
- sacl masko
- lac one,13 ; make and store frequency mask
- sub one
- sacl maskf
- lt one
- mpyk 3072 ; 1500Hz
- pac
- sacl freq
- lt one
- mpyk 4095 ; make and store high end of sweep range
- pac
- sacl highfq
- lt one
- mpyk 2400 ; make and store low end of sweep range
- pac
- sacl lowfq
- zac
- sub one
- sacl mone ; make and store minus one
- lac one,14
- sub one
- sacl mask ; make and store mask for modulo 16384 phase arithmetic
- lac one,6
- sub one
- sacl maskl ; make and store fine part of address mask;
- zac
- sacl inty
- sacl phase
- sacl clkph
- sacl tph
- sacl clkph
- lac one
- sacl sweep
- lt one
- mpyk 1638 ; make and store clock rate (1638 = 800 Hz)
- pac
- sacl clkfr
- lt one
- mpyk 3072
- pac
- sacl tfrq
-
- ; Okay the BS is over lets get to work !
-
- wait: bioz fire ; is it time for a new sample
- b wait ; nope go wait in the corner
- fire: in xn0,pa3 ; get a new sample here
-
- lac xn0,4
- sub one,15 ; Change ADC format to two's complement
- sacl xn0
-
- ; modulator/status/misc output
-
- lac bito,12
- addh masko
- sach yn0
- out yn0,pa4 ; send bito to DAC
- out bitpc,pa7 ; output control word to PC
- lac inty ; load the PC interrupt control word
- bz noi
- zac ; yes
- sacl inty
- out 6,6 ; tell the PC that we are ready
-
- ; end output
-
- ; Determine transmit bit timing
-
- noi: larp 1 ; transmit timing auxiliary register
- banz noty ; is time to tick the clock for the PC?
-
- lark ar1,19 ; yes,reset output bit counter
- zac
- sacl tcnt ; reset Manchester (split phase) counter
- lac one,2 ; get ready to tick the clock in the PC control word
- sacl c0
- lac bitpc ; load the control word
- xor c0 ; tick the <TX> clock
- sacl bitpc ; store the new PC control word
- lac inty
- or one
- sacl inty
- in c0,7 ; input the PC side control word
- lac one,4
- and c0 ; pick off the eye or modulator control bit
- sacl eom
- lac one,3 ; pick off the transmit bit
- and c0
- bgz tpo ; is it zero ?
- lac mone ; yes set bit multiplier to minus one
- sacl tbit
- b noty
- tpo: lac one ; No it is a one so set the multiplier to one
- sacl tbit
-
- noty:
-
-
- ; Manchester the bit
-
- lac tcnt ; Find out if we are half way through the bit
- sub one,3
- sub one,2 ; if tcnt is ten, it is time to split the bit
- bnz dnch ; if we are not half way, don't change it
- lt mone ; We are halfway so change the sign of the bit multiplier
- mpy tbit
- pac
- sacl tbit
- dnch: lac tcnt
- add one ; Increment ther Manchester (split phase) counter
- sacl tcnt
-
- ; Begin modulator
- lac eom
- bnz eye
- lac mone
- sacl modem ; real tone
- lack one ;
- sacl mps ; Restore sine and cosine quadrant multipliers
- sacl mpc ;
- lac tph
- add tfrq ; increment the modulator phase, tph, by the modulator frq, tfrq
- and mask
- sacl tph
- call tones ; get the sinusoid
- lt sine
- mpy tbit ; multiply by the bit
- pac
- sacl bito ; store for the DAC to output to the transmitter
-
-
- ; Begin demodulator
- eye: lack one
- sacl modem ; store control that makes complex tone
- lack one ;
- sacl mps ; Restore sine and cosine quadrant multipliers
- sacl mpc ;
- lac phase
- call tones ; go make complex tone
-
- lt xn0 ; load the current sample
- mpy cosine; multiply by cosine
- pac
- sach yn0,1 ; store it Q channel current sample
- mpy sine ; multiply sample by sine
- pac
- sach xn0,1 ; now store it in current sample place for I channel
-
- ; Low pass for each sample cutoff is at 800 Hz. Carrier is 20-25 dB down
-
- ; First lowpass I arm product to get the lower frequency mixer products
-
- zac
- ;
- lt xn22
- mpyk -117
- ;
- ltd xn21
- mpyk 675
- ;
- ltd xn20
- mpyk 647
- ;
- ltd xn19
- mpyk 325
- ;
- ltd xn18
- mpyk -453
- ;
- ltd xn17
- mpyk -1303
- ;
- ltd xn16
- mpyk -1513
- ;
- ltd xn15
- mpyk -459
- ;
- ltd xn14
- mpyk 1949
- ;
- ltd xn13
- mpy H9
- ;
- ltd xn12
- mpy H10
- ;
- ltd xn11
- mpy H11
- ;
- ltd xn10
- mpy H10
- ;
- ltd xn9
- mpy H9
- ;
- ltd xn8
- mpyk 1949
- ;
- ltd xn7
- mpyk -459
- ;
- ltd xn6
- mpyk -1513
- ;
- ltd xn5
- mpyk -1303
- ;
- ltd xn4
- mpyk -453
- ;
- ltd xn3
- mpyk 325
- ;
- ltd xn2
- mpyk 647
- ;
- ltd xn1
- mpyk 675
- ;
- ltd xn0
- mpyk -117
- ;
- apac
- ;
- sach xn0,1
-
- ; Now do the Q arm to get the lower frequency mixer products.
-
- zac
- ;
- lt yn22
- mpyk -117
- ;
- ltd yn21
- mpyk 675
- ;
- ltd yn20
- mpyk 647
- ;
- ltd yn19
- mpyk 325
- ;
- ltd yn18
- mpyk -453
- ;
- ltd yn17
- mpyk -1303
- ;
- ltd yn16
- mpyk -1513
- ;
- ltd yn15
- mpyk -459
- ;
- ltd yn14
- mpyk 1949
- ;
- ltd yn13
- mpy H9
- ;
- ltd yn12
- mpy H10
- ;
- ltd yn11
- mpy H11
- ;
- ltd yn10
- mpy H10
- ;
- ltd yn9
- mpy H9
- ;
- ltd yn8
- mpyk 1949
- ;
- ltd yn7
- mpyk -459
- ;
- ltd yn6
- mpyk -1513
- ;
- ltd yn5
- mpyk -1303
- ;
- ltd yn4
- mpyk -453
- ;
- ltd yn3
- mpyk 325
- ;
- ltd yn2
- mpyk 647
- ;
- ltd yn1
- mpyk 675
- ;
- ltd yn0
- mpyk -117
- ;
- apac
- ;
- sach yn0,1
-
- ; Okay we now have filtered products with data bauding pseudo base banded
- ; Let's close the loop and lock on
-
- lac xn0; Hard limit data line for phase error detector
- sacl bd0; Input data into delay line so that demanchester can occur at
- ; Zero crossing.
- bgez pdps ; is data baud a plus one ?
- lt yn0 ; get ready for a multiply
- mpyk -1 ; multiply phase error arm by -1
- pac
- sacl yn0
- pdps: lt carof
- mpyk 7 ; leaky integrate the phase error
- pac
- sacl cosy
- lac carof,15
- add cosy,12 ; take 7/8 of the old value and add it to the gain times
- add yn0,10 ; the current phase error observation. (LPF)
- sach carof
- ;; lac carof,3 ; uncomment these two lines to send the
- ;; sacl bito ; VCO error voltage out the D/A
- lac yn0,10 ; add a small amount of the current phase error to
- addh carof ; the integrator output.
- sach c0 ; this is the phase correction
- lac c0 ; load correction
- delph: add phase ; add the old phase
- add freq ; add the phase increment (frequency)
- and mask ; modulo 2*pi
- sacl phase ; store it for next sample complex tone generation step
- lac eom
- bz mod
- lac xn0 ; uncomment these two lines to send eye patterns out
- sacl bito ; the D/A port
- ; lac sine,11 ; uncomment these two to hear recovered carrier.
- ; sach bito
-
-
- ; Assuming lock, let's recover clock using a PLL on a nonlinearity
- ; generating a clock tone
-
- mod: lt xn0
- mpy xn0 ; square the current data arm value
- pac
- apac
- apac ; add it to the accumulator three times to raise the number
- ; of significant bits in the high word
- sach cd0,1 ; shift left 4 and store the high word
- lt clkav
- mpyk 3 ; we will LPF with an exponential decay filter to estimate
- pac ; the average amplitude of the clock signal. Multiply old
- sacl cosy
- lac cd0,13 ; load one sixteenth of the current clock signal value
- abs
- add clkav,15 ; value first by fifteen and then divide by 16.
- add cosy,13
- sach clkav
- lac cd0,2 ;load it shifting one up to increase significance
- sub clkav,2
- sacl cd0 ; subtract the average value, that is remove the DC.
- ; sacl bito
- lac mone
- sacl modem ; real tone
- lack one ;
- sacl mps ; Restore sine and cosine quadrant multipliers
- sacl mpc ;
- lac one,12 ; we are going to use the tone generator and we need
- sub clkph ; cosine so take pi/2 - phase and then find the sine of
- add one,14 ; that after doing mod 2*pi
- and mask
- call tones ; get the cosine (which will be the sine since we did
- ; lac sine,11
- ; sach bito ; un comment these two lines to see the clock tone
- lt sine ; complimentary angle
- mpy cd0 ; multiply by the current clock tone value
- pac
- sach cd0,1
-
- ; filter this product to get the clock signal phase error
- ; sine(clock phase)*cosine(clock phase estimate) yields the error signal
- ; LP Filter to get the lower frequency mixer products
- ; Filter with cutoff at 800 Hz, doesn't need to be a great filter, just
- ; the best you can do in 13 taps. 25+ dB rejection of the stuff at
- ; 1600.
-
- lt cd12
- mpyk -930
- pac
-
- ltd cd11
- mpyk -293
- apac
- dmov bd11
-
- ltd cd10
- mpyk 732
- apac
- dmov bd10
-
- ltd cd9
- mpyk 2571
- apac
- dmov bd9
-
- ltd cd8
- mpy ch4
- apac
- dmov bd8
-
-
- ltd cd7
- mpy ch5
- apac
- dmov bd7
-
- ltd cd6
- mpy ch6
- apac
- dmov bd6
-
- ltd cd5
- mpy ch5
- apac
- dmov bd5
-
- ltd cd4
- mpy ch4
- apac
- dmov bd4
-
- ltd cd3
- mpyk 2571
- apac
- dmov bd3
-
- ltd cd2
- mpyk 732
- apac
- dmov bd2
-
- ltd cd1
- mpyk -293
- apac
- dmov bd1
-
- ltd cd0
- mpyk -930
- apac
- dmov bd0
-
- sach clocke
-
- lt clkit
- mpyk 15 ; SLOW leak integrator, 31/32 old phase error plus
- pac
- sacl cosy
- ; lac clkit,15
- lac cosy,12
- ; add cosy,11
- ; lac clkit,11
- add clocke,11 ; 1/32 of the new phase error estimate
- sach clkit
- lac clocke,10 ; add 1/32 of the current phase error observation to
- add clkit,15 ; the integrated estimate
- sach clocke
- lac clocke ; load phase correction
-
- dlcph: add clkph ; add the old phase
- add clkfr ; add the phase increment (frequency)
- sacl clkph
- sub 1,14 ; if the phase is greater than two pi, we have hit a
- blz wait ; baud boundary, if not, go back to wait and start over
-
- ; We have crossed a baud boundary since the phase is >= 2^14.
-
- sacl clkph ; store it for next sample complex tone generation step
- ;
- ; We have had to comprimise. The most we could fit, due to constraints
- ; of 128 data memory data locations in page 0, is just over half the total
- ; bit into our delay line. HOWEVER, this is "the important half"
- ; It is the center and contains the "peaks" around the guaranteed
- ; zero crossing in the center of the bit. Convolve with the bit shape
- ; and get 0 or 1.
- ;
- ; de Manchester the bits in the delay line
- lt bd12
- mpyk 1024
- pac
- lt bd11
- mpyk 4095
- apac
- lt bd10
- mpyk 4095
- apac
- lt bd8
- mpyk 1024
- apac
- lt bd7
- mpyk 128
- apac
- lt bd5
- mpyk -128
- apac
- lt bd4
- mpyk -1024
- apac
- lt bd2
- mpyk -4095
- apac
- lt bd1
- mpyk -4095
- apac
- lt bd0
- mpyk -1024
- apac
- sach bit,4 ; Store the de-Manchestered bit
- ; There is an ambiguity in the clock since the clock tone recovery
- ; above runs at 800 Hz. We must decide which is the REAL bit center
- ; and then output that bit determined above. This is a statistical
- ; process. We are guaranteed a bit transition in center of each
- ; bit. If we are on the boundary, the occasional change from a zero
- ; to a one and vice versa causes NO transition. The process above
- ; Will yield a small positive number for abs(bit) when there is no
- ; transition
- lac bit
- larp 0 ; set auxiliary register pointer to the receive clock control.
- ; <RX> clock control register
- banz b1 ; is it bit time 0 or bit time 1
- bgz psb0 ; it is bit time zero. Is the bit positive?
- lac mone,10 ; No load -1
- sacl bit0 ; and store it in bit 0
- b rar0
- psb0: lac one,10
- sacl bit0
- rar0: lark ar0,1 ; reset the counter for the next two 2pi crossings.
- lac bit ; load bit for the bit time 0, take absolute value
- abs
- sacl bita0 ; store it for later
- b wait
- ; The bit time was 1 and not zero.
- b1: bgz psb1 ; is bit positive?
- lac mone,10 ; no so load -1
- sacl bit1 ; store it in bit one
- b rar1
- ; yes it is positive
- psb1: lac one,10 ; load one
- sacl bit1 ; store it in bit one
- rar1: lac bit ; load bit for the bit time 1, take absolute value
- abs
- sacl bita1 ; store it for later
- lack 13 ; load the accumulator with 1101 binary
- and bitpc ; use it mask the PC control word to destroy old bit.
- xor one ; tick the output clock
- sacl bitpc ; store it
- lac inty
- or one ; setup to interrupt PC with new control word
- sacl inty
- lac bita1 ; load the bit1 size
- sub bita0 ; sub the bit0 size
- add bitm0 ; integrate
- sacl bitm0 ; store it
- sub 1,12 ; let 4096 be the rails
- bgz th ; are we greater than 4096?
- lac bitm0 ; load it again
- add 1,12 ; add 4096
- blz tl ; still less than zero? < -4096?
- b dbt
- ; Yes we are greater than 4096, so make us 4096
- th: lac 1,12
- sacl bitm0
- b dbt
- ; Yes we are less than -4096, so make us -4096
- tl: zac
- sub one,12 ; load -4096
- sacl bitm0 ; store it
- dbt: lt bitm1
- mpyk 7 ; average with 31/32 times old + 1/32 * new
- pac
- sacl cosy
- lac bitm1,15
- lac cosy,12
- add bitm0,11
- sach bitm1
- lac bitm1
- ; sacl bito ; uncomment to see which clock phase was chosen for
- ; the true center of bit
- blz bi0 ; is the averaged size of bit0 bigger?
- ; NO
- lac bit1 ; load bit 1
- b outb ; jump to modify PC control word
- bi0: lac bit0
- outb:
- ; sacl bito ; uncomment to send bits out the D/A port
- blz wait ; if the bit is negative, bitpc is already setup
- lac one,1 ; if not we need to add a 1 in the 2's spot, i.e. add 2.
- or bitpc
- sacl bitpc ; store it in the PC control word
- outp: b wait ; go output and then do it again
-
- ; complex tone generator if modem>0 if modem<0 sine wave generator
-
- tones: sacl wkph ; store a working copy
- lac wkph,4
- subh one
- blz getem ; is it in a quadrant bigger than first?
- subh one
- bgez thfr; is it in a quadrant greater than two?
- lac 1,13 ; nope so load pi
- sub wkph ; subtract phase so that it maps back into 1st quad
- sacl wkph ; store
- lac mone ; load -1
- sacl mpc ; store it in the cosine multiplier
- b getem ; go read tables
- thfr: lac mone ; multiplier for bottom half
- sacl mps ; store
- lac wkph ;
- sub one,13 ; map angle back to upper half and go do it again
- b tones
- getem: lac wkph,10 ; take 1st quadrant phase equiv for sine and pick
- ; off coarse part of phase address
- sach coph ; store it
- lack sintbl ; load sine table offset into accumulator
- add coph ; add coarse address off set
- tblr sinx ; read the coarse sine value
- lac one,6 ; load pi/2
- sub coph ; subtract the coarse phase to get cosines offset
- sacl coph
- lack sintbl
- add coph ; do same as above for coarse cosine
- tblr cosx
- lac wkph ; load working phase
- and maskl ; mask off fine addres
- sacl coph ; store it
- lack fines ; locate fine table offset
- add coph ; add for offset into fine table
- tblr siny ; read table
- lack finec
- add coph
- tblr cosy
- zac
- lt sinx ; load sinx
- mpy cosy ; multiply by cosy
- lta siny ; load t reg with fine sin and accumulate previous prod.
- mpy cosx ; multiply by coarse cosx to use sin(X+Y)
- apac ; add the result to coarse sine
- sach sine ; store it.
- lac modem
- blz mult
- lac 1,12 ; load full address pi/2
- sub wkph ; subtract the working phase to get cosine
- sacl wkph
- lac wkph,10 ; from here to the later MARK it is identical to above
- sach coph
- lack sintbl
- add coph
- tblr sinx
- lac one,6
- sub coph
- sacl coph
- lack sintbl
- add coph
- tblr cosx
- lac wkph
- and maskl
- sacl coph
- lack fines
- add coph
- tblr siny
- lack finec
- add coph
- tblr cosy
- zac
- lt cosy
- mpy sinx
- lta siny
- mpy cosx
- apac ; MARK
- sach cosine ; store it in the cosine
- mult: lt mps; now we need to do a few multiplies by sign changes due to
- mpy sine ; to quadrant part of phase address
- pac; multiply sine by sine sign (:-) and
- sacl sine ; store the result
- lac modem
- bgz cosm
- ret
- cosm: mpy cosine; now multiply cosine by the same
- pac
- sacl cosine ; store it
- lt mpc; load cosine differentiator from sine sign (:-)
- mpy cosine; multiply
- pac
- sacl cosine ; store
- ret
- end
- ; Ebbly Ebbly Ebbly thats all folks
-
-